import java.awt.*;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.awt.event.*;

import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Part2DisplayPanel extends JPanel{
	private ArrayList<Matrix> letter1Segments;
	private ArrayList<Matrix> letter2Segments;
	private ArrayList<Matrix> letter3Segments;
	private ArrayList<ArrayList<Matrix>> letters;
	private int[] offset;
    private ArrayList<Line2D.Double> drawThese;
    private Matrix twoDRotation1;
    private Matrix twoDRotation2;
    private Matrix twoDRotation3;
    private double letter1Theta;
    private double letter2Theta;
    private double letter3Theta;
    private int count;
    private int letter1OriginY;
    private ArrayList<Matrix> rotations;
    private int count2;
    
	public Part2DisplayPanel(){
		offset = new int[]{50,160,270};
		letter1Segments = new ArrayList<Matrix>();
		letter2Segments = new ArrayList<Matrix>();
		letter3Segments = new ArrayList<Matrix>();
		letters=new ArrayList<ArrayList<Matrix>>();
		letter1OriginY=0;
		letter1Theta=0.15578145389701454075021372148493;
		letter2Theta=0.05192715129900484691673790716164*2;
		letter3Theta=0.25963575649502423458368953580822;
		count=0;
		count2=0;
		double [][] array2D1 = new double[][]{{Math.cos(letter1Theta), Math.sin(letter1Theta)}, {-1*
			Math.sin(letter1Theta), Math.cos(letter1Theta)}};
		double [][] array3DYAxis = new double [][]{{Math.cos(letter2Theta), 0, -1*Math.sin(letter2Theta)},{0,1,0},{Math.sin(letter2Theta),0, Math.cos(letter2Theta)}};
		double [][] array3DXAxis = new double [][]{{1,0,0},{0, Math.cos(letter3Theta), Math.sin(letter3Theta)}, {0, -1*Math.sin(letter3Theta), Math.cos(letter3Theta)}};
		twoDRotation1=new Matrix(array2D1);
		twoDRotation2=new Matrix(array3DYAxis);
		twoDRotation3=new Matrix(array3DXAxis);
		rotations=new ArrayList<Matrix>();
		rotations.add(twoDRotation1);
		rotations.add(twoDRotation2);
		rotations.add(twoDRotation3);
		drawThese=new ArrayList<Line2D.Double>();
		drawThese=setSegments();
		javax.swing.Timer timer = new javax.swing.Timer(1000/24, new ActionListener() {
	          public void actionPerformed(ActionEvent e) {
	        	  if(count2++<30){
	        		  
	        	  } else if(count++<121){
	        	  recalculate();	        	  
	        	  repaint();
	        	  }
	          }
	          
	       });

		timer.start();
		
	}
	
	
	
	
	public void recalculate(){
		for(int z=0; z<letters.size(); z++){
			for(int k=0; k<letters.get(z).size(); k++){
				if(z>0){
					double[] temp1= rotations.get(z).vectorMultiply(letters.get(z).get(k).getColumn(0));
					double[] temp2= rotations.get(z).vectorMultiply(letters.get(z).get(k).getColumn(1));
					double[] temp3= {0,0,0};
					double[][] temp4= new double[][]{temp1,temp2,temp3};
					letters.get(z).get(k).setTheMatrix(temp4);
				} else if (z==0){
					double[] column1 = rotations.get(z).vectorMultiply(letters.get(z).get(k).getColumn(0));
					double[] column2 = rotations.get(z).vectorMultiply(letters.get(z).get(k).getColumn(1));
					double[][] temp2 = new double[][]{column1, column2};
					letters.get(z).get(k).setTheMatrix(temp2);
				}
			}
		}
		drawThese=drawSegments();
	}
	public void paintComponent(Graphics g){	
		super.paintComponent(g);
		g.setColor(Color.blue);
		g.fillRect(0,0,500,500);
		Graphics2D g2d = (Graphics2D)g;		
		g2d.setColor(Color.red);	
		for(Line2D.Double i: drawThese){
			g2d.draw(i);	
		}
	}
		
	public ArrayList<Line2D.Double> setSegments(){
		letter1Segments.add(new Matrix(new double[][]{{-20,40},{20,40}}));	
		letter1Segments.add(new Matrix(new double[][]{{-10,30},{10,30}}));
		letter1Segments.add(new Matrix(new double[][]{{-10,-30},{10,-30}}));	
		letter1Segments.add(new Matrix(new double[][]{{-20,-40},{20,-40}}));
		letter1Segments.add(new Matrix(new double[][]{{-20,-40},{-20,40}}));	
		letter1Segments.add(new Matrix(new double[][]{{-10,-30},{-10,30}}));
		letter1Segments.add(new Matrix(new double[][]{{10,30},{10,-30}}));
		letter1Segments.add(new Matrix(new double[][]{{20,-40},{20,40}}));


		letter2Segments.add(new Matrix(new double[][]{{-5,-30,0},{-5,30,0},{0,0,0}}));
		letter2Segments.add(new Matrix(new double[][]{{5,-30,0},{5,30,0},{0,0,0}}));
		letter2Segments.add(new Matrix(new double[][]{{-5,30,0},{-15,30,0},{0,0,0}}));
		letter2Segments.add(new Matrix(new double[][]{{5,30,0},{15,30,0},{0,0,0}}));
		letter2Segments.add(new Matrix(new double[][]{{5,-30,0},{15,-30,0},{0,0,0}}));
		letter2Segments.add(new Matrix(new double[][]{{-5,-30,0},{-15,-30,0},{0,0,0}}));
		letter2Segments.add(new Matrix(new double[][]{{-15,-40,0},{15,-40,0},{0,0,0}}));
		letter2Segments.add(new Matrix(new double[][]{{-15,40,0},{15,40,0},{0,0,0}}));
		

		letter2Segments.add(new Matrix(new double[][]{{-15,30,0},{-15,40,0},{0,0,0}}));
		letter2Segments.add(new Matrix(new double[][]{{15,30,0},{15,40,0},{0,0,0}}));
		letter2Segments.add(new Matrix(new double[][]{{-15,-30,0},{-15,-40,0},{0,0,0}}));
		letter2Segments.add(new Matrix(new double[][]{{15,-30,0},{15,-40,0},{0,0,0}}));
		

		letter3Segments.add(new Matrix(new double[][]{{-5, -40, 0}, {-5, 30, 0}, {0,0,}}));
		letter3Segments.add(new Matrix(new double[][]{{5, -40, 0}, {5, 30, 0}, {0,0,0}}));
		letter3Segments.add(new Matrix(new double[][]{{-5, -40, 0}, {5, -40, 0}, {0,0,0}}));
		letter3Segments.add(new Matrix(new double[][]{{-25, 40, 0}, {25, 40, 0}, {0,0,0}}));
		letter3Segments.add(new Matrix(new double[][]{{-25, 40, 0}, {-5, 40, 0}, {0,0,0}}));
		letter3Segments.add(new Matrix(new double[][]{{5, 30, 0}, {25, 30, 0}, {0,0,0}}));
		letter3Segments.add(new Matrix(new double[][]{{-5, 30, 0}, {-25, 30, 0}, {0,0,0}}));
		letter3Segments.add(new Matrix(new double[][]{{-25, 30, 0}, {-25, 40, 0}, {0,0,0}}));
		letter3Segments.add(new Matrix(new double[][]{{25, 30, 0}, {25, 40, 0}, {0,0,0}}));

		letters.add(letter1Segments);
		letters.add(letter2Segments);
		letters.add(letter3Segments);
		
		return drawSegments();		
	}
	public ArrayList<Line2D.Double> drawSegments(){
		ArrayList<Line2D.Double> allSegments = new ArrayList<Line2D.Double>();
		for(int z=0; z<letters.size();z++){
			for (int k=0; k<letters.get(z).size();k++){
				ArrayList<Double> coordinates = new ArrayList<Double>();
				for (int i=0; i<2; i++){
					double[] arrayCol1=letters.get(z).get(k).getColumn(i);
					int length=arrayCol1.length;
					if(z==0){
						for(int j= 0; j<length; j++){						
							coordinates.add(arrayCol1[j]);
						}						
					} else {
						double[] coordinate = calculateZ(letters.get(z).get(k).getColumn(i), z);
						coordinates.add(coordinate[0]);
						coordinates.add(coordinate[1]);
						
					}
				}
				Line2D.Double segment = new Line2D.Double(coordinates.get(0)+offset[z], 
						letter1OriginY-coordinates.get(1)+offset[0],coordinates.get(2)+offset[z],letter1OriginY-coordinates.get(3)+offset[0]);
				allSegments.add(segment);	
				}
			}	
		return allSegments;
		
	}
	public double[] calculateZ(double[] column, int letter){
		double[] coordinate={};
		double x,y,z;
		x=column[0];
		y=column[1];
		z=column[2];
		if (letter==1){
			double finalX, finalY;
			finalX=x+z*Math.sin(letter2Theta);
			finalY=y;
			coordinate = new double[]{finalX, finalY};
		}
		if (letter==2){
			double finalX, finalY;
			finalX=x;
			finalY=y+z*Math.sin(letter3Theta);
			coordinate = new double[]{finalX, finalY};
		}
		return coordinate;		
	}
	
}
